/******************************************************************************
 * 
 * Announce: CSharpKit, Basic algorithms, components and definitions.
 *           Copyright (C) ShenYongchen.
 *           All rights reserved.
 *   Author: 申永辰.郑州 (shenyczz@163.com)
 *  WebSite: http://github.com/shenyczz/CSharpKit
 *
 * THIS CODE IS LICENSED UNDER THE MIT LICENSE (MIT).
 * THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 
 * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
 * IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
 * PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
 * 
******************************************************************************/

namespace CSharpKit.SVM
{
    /// <summary>
    /// 范围转换<br/>
    /// 规范化对节点数据？
    /// </summary>
    public interface IRangeTransform
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="input">Input value</param>
        /// <param name="index">Index of the transform to use</param>
        /// <returns></returns>
        double Transform(double input, int index);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="input">The array to transform</param>
        /// <returns></returns>
        SvmNode[] Transform(SvmNode[] input);
    }



    public static class IRangeTransformExtensions
    {
        /// <summary>
        /// 处理SvmProblems的缩放，使它们在所有维度上都有均匀的范围，以获得更好的支持向量机性能。
        /// </summary>
        /// <param name="range">IRangeTransform</param>
        /// <param name="prob">数据集</param>
        /// <returns></returns>
        public static SvmProblem Scale(this IRangeTransform range, SvmProblem prob)
        {
            var result = new SvmProblem(prob.Count, new double[prob.Count], new SvmNode[prob.Count][], prob.MaxIndex);

            for (int i = 0; i < result.Count; i++)
            {
                // nodes
                result.X[i] = new SvmNode[prob.X[i].Length];
                for (int j = 0; j < result.X[i].Length; j++)
                {
                    result.X[i][j] = new SvmNode(prob.X[i][j].Index, range.Transform(prob.X[i][j].Value, prob.X[i][j].Index));
                }

                // Labels
                result.Y[i] = prob.Y[i];
            }

            return result;
        }


        //}}@@@
    }


}
